/**
 * 此js用于生成table的一些公共方法、data，简化table的操作
 */
const DEFAULT_ALIGN_CENTER_TYPES = ['index', 'selection', 'expand']
import {
  service as request,
  globals
} from '@/utils/request'
import Pagination from '@/components/Pagination'
export default {
  components: {
    Pagination
  },
  props: {
    // table加载数据的url
    url: {
      type: String,
      default: ''
    },
    columns: {
      type: Array,
      default() {
        return []
      }
    },
    // 是否需要序号列
    tableIndex: {
      type: Boolean,
      default: false
    },
    // 是否需要选择框列
    tableSelection: {
      type: Boolean,
      default: true
    },
    // 是否需要高级搜索
    isNeedAdvanceSearch: {
      type: Boolean,
      default: true
    },
    // 是否需要普通搜索，包括common和selection
    isNeedCommonSearch: {
      type: Boolean,
      default: true
    },
    // 是否需要导出按钮
    isNeedExport: {
      type: Boolean,
      default: true
    },
    // 是否需要分页器
    pagination: {
      type: Boolean,
      default: true
    },
    // 支持common、selection
    commonSearchType: {
      type: String,
      default: 'common'
    },
    commonSearchFormLabelWidth: {
      type: String,
      default: '120px'
    },
    advanceSearchFormLabelWidth: {
      type: String,
      default: '120px'
    },
    tableIndexFixed: String,
    tableSelectionFixed: String,
    // 支持common  mini2种方式
    type: {
      type: String,
      default: 'common'
    },
    excelFileName: {
      type: String,
      default: '导出文件'
    }
  },
  filters: {
    moneyFilter(num) {
      num = parseFloat(num).toFixed(2).toString().split('.')
      num[0] = num[0].replace(new RegExp('(\\d)(?=(\\d{3})+$)', 'ig'), '$1,')
      return num.join('.')
    }
  },
  data() {
    return {
      loading: false, // table是否在加载中
      insideTableData: [], // table绑定的数据
      total: 0, // 总数据条数
      query: {
        pageNum: 1,
        pageSize: 20
      },
      order: {}, // 排序，传给后台
      insideColumns: [],
      commonSearchForm: {
        items: []
      },
      commonSearchKeys: [],
      commonSearchKey: [],
      commonSearchValue: '',
      advanceSearchForm: {
        items: []
      },
      advanceSearchModal: false,
      downloadingExcel: false,
      excelProps: [], // 导出的列
      eltableSelection: [],
      param: {
        start: 0,
        length: 20
      }
    }
  },
  methods: {
    initData() {
      if (this.url) {
        this.loading = true
        request({
          url: this.url,
          method: 'get',
          params: this.param
        }).then(data => {
          this.insideTableData = data.data
          this.total = data.recordsTotal || 0
          this.loading = false
          this.$emit('param-change', this.param)
        }).catch(error => {
          this.loading = false
        })
      }
    },
    handleColumns(columns) {
      // 清空高级查询的form
      this.advanceSearchForm.items = []
      this.commonSearchForm.items = []
      // 清空普通查询
      this.commonSearchColumns = []
      // 清空导出用的excel列
      this.excelProps = []
      // 处理columns
      this.initInsideColumns(columns)
    },
    // 插入序号列
    initTableIndexColumn() {
      if (this.tableIndex) {
        this.insideColumns.unshift({
          type: 'index',
          minWidth: 30,
          maxWidth: 100,
          align: 'center',
          label: '序号',
          showOverflowTooltip: true,
          tooltip: true,
          datatype: 'index',
          indexMethod: row => {
            return row.initRowIndex + (this.pageSize * (this.currentPage - 1)) + 1
          }
        })
      }
    },
    // 插入选择列
    initTableSelectionColumn() {
      if (this.tableSelection) {
        this.insideColumns.unshift({
          type: 'selection',
          width: 50,
          align: 'center',
          datatype: 'index'
        })
      }
    },
    handleColumn(column) {
      column.slot = column.slot || false
      if (column.advanceSearchAble !== false) {
        column.advanceSearchAble = true
      }
      if (column.exportExcel !== false) {
        column.exportExcel = true
      }
      column.commonSearchAble = column.commonSearchAble || false
      // 默认不隐藏
      column.hidden = column.hidden || false
      // 数据类型默认为string
      column.datatype = column.datatype || 'string'
      // 表头默认居中
      column.headerAlign = column.headerAlign || 'center'
      // 除操作栏外，默认均有tooltip
      if (column.prop !== 'action') {
        column.tooltip = column.tooltip || true
      }

      this.handleColumnAlign(column)
      this.handleColumnExport(column)
    },
    handleColumnExport(column) {
      if (column.exportExcel) {
        this.excelProps.push(column)
      }
    },
    handleColumnAlign(column) {
      if (DEFAULT_ALIGN_CENTER_TYPES.includes(column.type)) {
        column.align = 'center'
        return
      }
      if (column.prop === 'action') {
        column.align = 'center'
        return
      }
      this.handleSearchColumn(column)
    },
    /**
     * 处理搜索数据
     * @param {Object} column
     */
    handleSearchColumn(column) {
      switch (column.datatype) {
        case 'string':
          this.handleColumnString(column)
          break
        case 'datetime':
          this.handleColumnDate(column)
          break
        case 'date':
          this.handleColumnDate(column)
          break
        case 'number':
          this.handleColumnNumber(column)
          break
        case 'money':
          this.handleColumnNumber(column)
          break
        case 'dic':
          this.handleColumnDic(column)
          break
        default:
          this.handleColumnString(column)
      }
    },
    /**
     * 当数据类型为string时，align默认为center
     * @param {Object} column
     */
    handleColumnString(column) {
      // column.align = column.align || 'left'
      column.align = column.align || 'center'
      if (column.commonSearchAble) {
        this.commonSearchForm.items.push({
          'key': '',
          'title': column.label,
          'datatype': column.datatype,
          'name': column.prop
        })
      }
      if (column.advanceSearchAble) {
        this.advanceSearchForm.items.push({
          'key': '',
          'title': column.label,
          'datatype': column.datatype,
          'name': column.prop
        })
      }
    },
    /**
     * 处理日期格式数据
     * @param {Object} column
     */
    handleColumnDate(column) {
      column.align = column.align || 'center'
      if (column.commonSearchAble) {
        this.commonSearchForm.items.push({
          'key': '',
          'title': column.label,
          'datatype': column.datatype,
          'name': column.prop
        })
      }
      if (column.advanceSearchAble) {
        this.advanceSearchForm.items.push({
          'key': '',
          'title': column.label,
          'datatype': column.datatype,
          'name': column.prop
        })
      }
    },
    /**
     * 处理数据格式的数据
     * @param {Object} column
     */
    handleColumnNumber(column) {
      // column.align = column.align || 'right'
      column.align = column.align || 'center'
      if (column.commonSearchAble) {
        this.commonSearchForm.items.push({
          'keyfrom': '',
          'keyto': '',
          'title': column.label,
          'datatype': column.datatype,
          'name': column.prop
        })
      }
      if (column.advanceSearchAble) {
        this.advanceSearchForm.items.push({
          'keyfrom': '',
          'keyto': '',
          'title': column.label,
          'datatype': column.datatype,
          'name': column.prop
        })
      }
    },
    handleColumnDic(column) {
      column.align = column.align || 'center'
      let key = ''
      if (column.defaultSearchValue) {
        key = column.defaultSearchValue
        this.param[column.prop] = key
      }
      if (column.commonSearchAble) {
        this.commonSearchForm.items.push({
          'key': key,
          'title': column.label,
          'datatype': column.datatype,
          'name': column.prop,
          'groupName': column.groupName
        })
      }
      if (column.advanceSearchAble) {
        this.advanceSearchForm.items.push({
          'key': key,
          'title': column.label,
          'datatype': column.datatype,
          'name': column.prop,
          'groupName': column.groupName
        })
      }
    },
    /**
     * 获取prop
     */
    getFormItemProp(index, datatype) {
      return 'items.' + index + '.prop'
    },
    // 驼峰命名转换为下划线命名
    humpToLine(name) {
      return name.replace(/([A-Z])/g, '_$1').toLowerCase()
    },
    lintToHump(name) {
      return name.replace(/\_(\w)/g, function(all, letter) {
        return letter.toUpperCase()
      })
    },
    initInsideColumns(columns) {
      this.insideColumns = columns.map((item, index) => {
        const res = item
        this.handleColumn(res)
        return res
      })
    },
    advanceSearchModalOnAsyncOk() {
      const param = this.getAdvanceParam()
      if (param) {
        this.param = param
        this.initData()
        this.advanceSearchModal = false
      }
    },
    resetAdvanceSearchForm(name) {
      // this.$refs[name].resetFields()
      this.advanceSearchForm.items.forEach(value => {
        if (value.datatype === 'string') {
          value.key = ''
        }
        if (value.datatype === 'date' || value.datatype === 'datetime') {
          value.key = []
        }
        if (value.datatype === 'number' || value.datatype === 'money') {
          value.keyfrom = ''
          value.keyto = ''
        }
        if (value.datatype === 'dic') {
          value.key = ''
        }
      })
    },
    commonSearch() {
      if (this.commonSearchValue.length > 0 && this.commonSearchKey.length <= 0) {
        this.$msgSuccess('请选择要检索的数据', 'warning')
        return
      }
      const param = this.getCommonParam()
      this.param = param
      this.initData()
    },
    /**
     * 开启一次普通搜索，pageSize改为1
     */
    getCommonParam() {
      this.query.pageNum = 1
      const start = this.query.pageSize * (this.query.pageNum - 1)
      const param = {
        'length': this.query.pageSize,
        'start': start
      }
      this.commonSearchKey.forEach(item => {
        param[item] = this.commonSearchValue
      })
      return param
    },
    getAdvanceParam() {
      this.query.pageNum = 1
      const start = this.query.pageSize * (this.query.pageNum - 1)
      const param = {
        'length': this.query.pageSize,
        'start': start
      }
      let allTest = true
      this.advanceSearchForm.items.forEach(value => {
        if (value.datatype === 'string' && value.key.length > 0) {
          param[value.name] = value.key
        }
        if ((value.datatype === 'date' || value.datatype === 'datetime') && value.key && value.key.length > 0) {
          const fromKey = value.name + 'Start'
          const toKey = value.name + 'End'
          param[fromKey] = value.key[0]
          param[toKey] = value.key[1]
        }
        if ((value.datatype === 'number' || value.datatype === 'money') && (value.keyfrom || value.keyto)) {
          const reg = /^(\-|\+)?\d+(\.\d+)?$/
          const t = this.$t(value.title)
          if (!reg.test(value.keyfrom)) {
            allTest = false
            this.$msgSuccess(this.$t('table.searchFormValidate.numStart', {
              t: t
            }), 'error')
          }
          if (!reg.test(value.keyto)) {
            allTest = false
            this.$msgSuccess(this.$t('table.searchFormValidate.numEnd', {
              t: t
            }), 'error')
          }
          const fromKey = value.name + 'Start'
          const toKey = value.name + 'End'
          if (value.keyfrom.length > 0) {
            param[fromKey] = value.keyfrom
          }
          if (value.keyto.length > 0) {
            param[toKey] = value.keyto
          }
        }
        if (value.datatype === 'dic') {
          if (value.key.length > 0) {
            param[value.name] = value.key
          }
        }
      })
      if (allTest) {
        return param
      } else {
        return false
      }
    },
    commonAdvanceSearch() {
      const param = this.getCommonAdvanceParam()
      if (param) {
        this.param = param
        this.initData()
      }
    },
    getCommonAdvanceParam() {
      this.query.pageNum = 1
      const start = this.query.pageSize * (this.query.pageNum - 1)
      const param = {
        'length': this.query.pageSize,
        'start': start
      }
      let allTest = true
      this.commonSearchForm.items.forEach(value => {
        const t = this.$t(value.title)
        if (value.datatype === 'string' && value.key.length > 0) {
          param[value.name] = value.key
        }
        if ((value.datatype === 'date' || value.datatype === 'datetime') && value.key.length > 0) {
          const fromKey = value.name + 'Start'
          const toKey = value.name + 'End'
          param[fromKey] = value.key[0].getTime()
          param[toKey] = value.key[1].getTime()
        }
        if (value.datatype === 'number' || value.datatype === 'money') {
          const reg = /^(\-|\+)?\d+(\.\d+)?$/
          if (!reg.test(value.keyfrom)) {
            allTest = false
            this.$msgSuccess(this.$t('table.searchFormValidate.numStart', {
              t: t
            }), 'error')
          }
          if (!reg.test(value.keyto)) {
            allTest = false
            this.$msgSuccess(this.$t('table.searchFormValidate.numEnd', {
              t: t
            }), 'error')
          }
          const fromKey = value.name + 'Start'
          const toKey = value.name + 'End'
          if (value.keyfrom.length > 0) {
            param[fromKey] = value.keyfrom
          }
          if (value.keyto.length > 0) {
            param[toKey] = value.keyto
          }
        }
        if (value.datatype === 'dic') {
          if (value.key.length > 0) {
            param[value.name] = value.key
          }
        }
      })
      if (allTest) {
        return param
      }
      return false
    },
    onSortChange(p) {},
    handleTableIndex(index, h) {
      return (this.query.pageNum - 1) * this.query.pageSize + index + 1
    },
    // 当用户手动勾选数据行的 Checkbox 时触发的事件
    onSelect(selection, row) {
      this.$emit('select', selection, row)
    },
    // 当用户手动勾选全选 Checkbox 时触发的事件
    onSelectAll(selection) {
      this.$emit('select-all', selection)
    },
    // 当选择项发生变化时会触发该事件
    onSelectionChange(selection) {
      this.eltableSelection = selection
      this.$emit('selection-change', selection)
    },
    // 当单元格 hover 进入时会触发该事件
    onCellMouseEnter(row, column, cell, event) {
      this.$emit('cell-mouse-enter', row, column, cell, event)
    },
    // 当单元格 hover 退出时会触发该事件
    onCellMouseLeave(row, column, cell, event) {
      this.$emit('cell-mouse-leave', row, column, cell, event)
    },
    // 当某个单元格被点击时会触发该事件
    onCellClick(row, column, cell, event) {
      this.$emit('cell-click', row, column, cell, event)
    },
    // 当某个单元格被双击击时会触发该事件
    onCellDblClick(row, column, cell, event) {
      this.$emit('cell-dblclick', row, column, cell, event)
    },
    // 当某一行被点击时会触发该事件
    onRowClick(row, column, event) {
      this.$emit('row-click', row, column, event)
    },
    // 当某一行被鼠标右键点击时会触发该事件
    onRowContextmenu(row, column, event) {
      this.$emit('row-contextmenu', row, column, event)
    },
    // 当某一行被双击时会触发该事件
    onRowDblClick(row, column, event) {
      this.$emit('row-dblclick', row, column, event)
    },
    // 当某一列的表头被点击时会触发该事件
    onHeaderClick(column, event) {
      this.$emit('header-click', column, event)
    },
    // 当某一列的表头被点击时会触发该事件
    onHeaderContextmenu(column, event) {
      this.$emit('header-contextmenu', column, event)
    },
    // 当表格的当前行发生变化的时候会触发该事件，如果要高亮当前行，请打开表格的 highlight-current-row 属性
    onCurrentChange(currentRow, oldCurrentRow) {
      this.$emit('current-change', currentRow, oldCurrentRow)
    },
    handleDownloadExcelCommand(command) {
      switch (command) {
        case 'selection':
          this.handleDownloadSelection()
          break
        case 'current':
          this.handleDownloadCurrent()
          break
        case 'all':
          this.handleDownloadAll()
          break
        default:
          this.handleDownloadCurrent()
          break
      }
    },
    /**
     * 导出当前页
     */
    handleDownloadCurrent() {
      if (this.insideTableData.length > 0) {
        this.handleExport(this.insideTableData)
      } else {
        this.$msgSuccess(this.$t('table.exportExcel.nodata'), 'error')
      }
    },
    /**
     * 导出选中
     */
    handleDownloadSelection() {
      if (this.eltableSelection.length <= 0) {
        this.$msgSuccess(this.$t('table.exportExcel.noselection'), 'error')
        return
      }
      this.handleExport(this.eltableSelection)
    },
    /**
     * 导出全部
     */
    handleDownloadAll() {
      if (this.url) {
        this.$msgSuccess(this.$t('table.exportExcel.allLimit'), 'success')
        this.downloadLoading = true
        const downloadParam = Object.assign({}, this.param)
        downloadParam.start = 0
        downloadParam.length = 5000
        request({
          url: this.url,
          method: 'get',
          params: downloadParam
        }).then(data => {
          this.handleExport(data.data)
          this.downloadLoading = false
        }).catch(error => {
          this.downloadLoading = false
        })
      }
    },
    // 导出
    handleExport(list) {
      this.downloadLoading = true
      import('@/vendor/Export2Excel').then(excel => {
        const tHeader = this.getExcelLabels()
        const filterVal = this.excelProps
        const data = this.formatJson(filterVal, list)
        const newData = data.map(item => {
          return item
        })
        const title = ['锚地船舶', '', '', '', '', '', '', '', ''] // 标题
        const merges = ['A1:I1'] // 合并单元格
        excel.export_json_to_excel({
          header: tHeader,
          data: newData,
          filename: this.excelFileName + ' ' + new Date().getTime(),
          autoWidth: true,
          bookType: 'xlsx'
        })
        this.downloadLoading = false
      })
    },
    formatJson(filterVal, jsonData) {
      return jsonData.map(v => filterVal.map(j => {
        if (j.datatype === 'dic') {
          return this.getDicName(j.groupName, v[j.prop])
        } else {
          return v[j.prop]
        }
      }))
    },
    getExcelLabels() {
      const labels = []
      this.excelProps.forEach(item => {
        if (this.$t(item.label) != '操作') labels.push(this.$t(item.label))
      })
      return labels
    },
    initOpenAdvanceSearchDialog() {
      const queryParam = this.param
      for (const key in queryParam) {
        this.advanceSearchForm.items.some(item => {
          if (item.name === key) {
            console.log(queryParam[key])
            item.key = queryParam[key]
          }
        })
      }
      this.advanceSearchModal = true
    }
  },
  mounted() {
    this.handleColumns(this.columns)
    this.initData()
  },
  watch: {
    columns: {
      handler: function(nv, ov) {
        this.handleColumns(nv)
      },
      deep: true
    },
    url: {
      handler: function(nv, ov) {
        this.initData()
      }
    }
  }
}
